package com.easymin.weixin.aop;

import java.text.DateFormat;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.easymin.weixin.common.AesUtil;
import com.easymin.weixin.common.DateDeserializer;
import com.easymin.weixin.common.DateSerializer;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

@Aspect
@Component
public class EncryptWxAop{


	@Pointcut("execution(public * com.easymin.weixin.controller.*.*.*(..))")
	public void pointCutApi() {

	}


	@Around("pointCutApi()")
	public Object pointCutApi(ProceedingJoinPoint thisJoinPoint) throws Throwable {

		RequestAttributes ra = RequestContextHolder.getRequestAttributes();
		ServletRequestAttributes sra = (ServletRequestAttributes) ra;
		HttpServletRequest request = sra.getRequest();

		String x_type = request.getHeader("X-type");

		return dataHandle(x_type,thisJoinPoint);

	}


	private Object dataHandle(String x_type,ProceedingJoinPoint thisJoinPoint) throws Throwable {

		Object args[] = thisJoinPoint.getArgs();

//    	if(true){
		if(StringUtils.isNotBlank(x_type) && x_type.equals("sign")){
//    		if(null!=args && args.length>0){
//        		for (int i = 0; i < args.length; i++) {
//        			Object obj = args[i];
//        			System.out.println(obj);
//        			if(null!=obj){
//        				args[i]=AesUtil.aesDecrypt(String.valueOf(obj), AesUtil.VIPARA);
//        			}
//            	}
//        	}

			Object obj = thisJoinPoint.proceed(args);

			if(obj instanceof com.easymin.weixin.controller.v4.ResultTransport){
				com.easymin.weixin.controller.v4.ResultTransport result = (com.easymin.weixin.controller.v4.ResultTransport)obj;
				Object data = result.getData();
				if(null!=data){
					Gson gson = createGson();
					result.setData(AesUtil.aesEncrypt(String.valueOf(gson.toJson(data)) , AesUtil.VIPARA));
					return result;
				}
				else{
					return obj;
				}
			}
			else if(obj instanceof Map){
				@SuppressWarnings("unchecked")
				Map<String, Object> map = (Map<String, Object>)obj;

				Object code = map.get("code");
				Object data = map.get("data");
				Object success = map.get("success");

				if(null!=success){

					if(null!=data){
						Gson gson = createGson();
						map.put("data",AesUtil.aesEncrypt(String.valueOf(gson.toJson(data)) , AesUtil.VIPARA));
						return map;
					}
					else{
						Iterator<Entry<String, Object>> it = map.entrySet().iterator();
						while(it.hasNext()){
							Entry<String, Object> itEntry = it.next();
							Object itKey = itEntry.getKey();
							Object itValue = itEntry.getValue();
							if(!String.valueOf(itKey).equals("success")){
								if(null!=itValue){
									itEntry.setValue(AesUtil.aesEncrypt(String.valueOf(itValue) , AesUtil.VIPARA));
								}
							}
						}
						return map;
					}

				}
				else if(null!=code){
					if(null!=data){
						Gson gson = createGson();
						map.put("data",AesUtil.aesEncrypt(String.valueOf(gson.toJson(data)) , AesUtil.VIPARA));
						return map;
					}
					else{
						return obj;
					}
				}
				else{
					return obj;
				}
			}
			else if(obj instanceof ResponseEntity){
				ResponseEntity responseEntity = (ResponseEntity)obj;
				Object body = responseEntity.getBody();
				if(null!=body){
					if(body instanceof com.easymin.weixin.common.transport.Result){
						com.easymin.weixin.common.transport.Result result = (com.easymin.weixin.common.transport.Result)body;
						Object data = result.getData();
						if(null!=data){
							Gson gson = createGson();
							result.setData(AesUtil.aesEncrypt(String.valueOf(gson.toJson(data)) , AesUtil.VIPARA));
							return new ResponseEntity<Object>(result, responseEntity.getStatusCode());
						}
						else{
							return obj;
						}
					}
					else{
						return obj;
					}
				}
				else{
					return obj;
				}
			}
			else if(obj instanceof com.easymin.weixin.common.transport.Result){
				com.easymin.weixin.common.transport.Result result = (com.easymin.weixin.common.transport.Result)obj;
				Object data = result.getData();
				if(null!=data){
					Gson gson = createGson();
					result.setData(AesUtil.aesEncrypt(String.valueOf(gson.toJson(data)) , AesUtil.VIPARA));
					return result;
				}
				else{
					return obj;
				}
			}
			else{
				return obj;
			}
		}
		else{
			Object obj = thisJoinPoint.proceed(args);
			return obj;
		}
	}

	private static Gson createGson(){
		GsonBuilder gb = new GsonBuilder();
		gb.registerTypeAdapter(java.util.Date.class, new DateSerializer()).setDateFormat(DateFormat.LONG);
		gb.registerTypeAdapter(java.util.Date.class, new DateDeserializer()).setDateFormat(DateFormat.LONG);
		Gson gson = gb.create();
		return gson;
	}

}